package com.nine.gxh.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.nine.gxh.dtos.GxhInfoChannelDto;
import com.nine.gxh.mapper.GxhInfoChannelMapper;
import com.nine.gxh.model.GxhInfoChannel;
import com.nine.gxh.service.GxhInfoChannelLogService;
import com.nine.gxh.service.GxhInfoChannelService;
import com.nine.gxh.vos.GxhInfoChannelVo;
import com.ruoyi.common.constant.MyRabbitConstants;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author: duonine
 * @date: 2023/7/3
 */
@Service
@Slf4j
public class GxhInfoChannelServiceImpl extends ServiceImpl<GxhInfoChannelMapper, GxhInfoChannel> implements GxhInfoChannelService {

    @Resource
    private GxhInfoChannelLogService channelLogService;

    @Resource
    private RabbitTemplate rabbitTemplate;

    /**
     * 此时执行的流程就是，先将主程序日志都打印完，然后异步方法执行
     *
     * @param dto
     * @return
     */
    @Override
    public IPage<GxhInfoChannel> listAll(GxhInfoChannelDto dto) {

        log.info("listAll:::检查前参数{}", dto);
        // 检查参数
        dto.checkPage();
        log.info("listAll:::检查后参数{}", dto);

        IPage<GxhInfoChannel> page = new Page<>(dto.getPageno(), dto.getPagesize());

        // 构造 GxhInfoChannel 搜索条件
        LambdaQueryWrapper<GxhInfoChannel> wrapper = Wrappers.lambdaQuery();
        // 名称模糊查询
        wrapper.like(StringUtils.hasText(dto.getName()), GxhInfoChannel::getName, dto.getName());
        // 分类查询
        wrapper.eq(StringUtils.hasText(dto.getCtype()), GxhInfoChannel::getCtype, dto.getCtype());

        // 日期区间查询
        if (dto.getQuerydate() != null && dto.getQuerydate().length == 2) {
            wrapper.between(GxhInfoChannel::getCreatedate, dto.getQuerydate()[0], dto.getQuerydate()[1]);
        }

        // 根据排序值倒序
        wrapper.orderByDesc(GxhInfoChannel::getOrdernum);
        page = this.baseMapper.selectPage(page, wrapper);

        log.info("测试异步功能【主方法--开始】。。。。。。。。。。。。。。。。。");
        // 异步：将操作日志，存放到 gxh_info_channel_log 中
        channelLogService.saveChannelLog();
        log.info("测试异步功能【主方法--结束】。。。。。。。。。。。。。。。。。");

        return page;
    }

    @Override
    public List<GxhInfoChannel> listByXml(GxhInfoChannelDto dto) {
        List<GxhInfoChannel> channelList = this.baseMapper.listByXml();
        return channelList;
    }

    /**
     * 新增channel
     *
     * @param dto
     * @return
     */
    @Override
    public GxhInfoChannel addChannel(GxhInfoChannelDto dto) {
        GxhInfoChannel channel = new GxhInfoChannel();
        BeanUtils.copyProperties(dto, channel);
        // 额外的数据，需要单独设置
        channel.setCreatedate(new Date());

        boolean flag = this.save(channel);

        if (flag) {
            log.info("测试mq的消息队列功能【发放与接收】。。。。。。。。。。。。。。。。。");

            Map<String, Object> map = new HashMap<>();
            map.put("name", "测试001");
            map.put("content", "内容信息001");

            try {
                ObjectMapper mapper = new ObjectMapper();
                // 将 map 数据转换为 string 进行传递
                String value = mapper.writeValueAsString(map);
                rabbitTemplate.convertAndSend(MyRabbitConstants.CHANNEL_EXCHANGE_NAME, MyRabbitConstants.CHANNEL_ROUTE_NAME, value);
            }
            catch (JsonProcessingException e) {
                throw new RuntimeException(e);
            }
            // 保存日志，操作类型：新增【1】
            channelLogService.saveChannelLog(channel.getId(), "1");
        }

        return channel;
    }

    @Override
    public boolean delChannel(String channelId) {
        log.info("频道删除，id为：{}", channelId);
        // 将String转为Long进行查询
        boolean flag = this.removeById(Long.parseLong(channelId));
        return flag;
    }

    @Override
    public boolean delChannelBatch(List<String> ids) {
        this.removeByIds(ids);
        return false;
    }

    @Override
    public GxhInfoChannel updateChannel(GxhInfoChannelDto dto) {

        GxhInfoChannel channel = new GxhInfoChannel();
        BeanUtils.copyProperties(dto, channel);
        // 将传递的String id 转换为 Long id
        channel.setId(Long.parseLong(dto.getId()));
        channel.setCreatedate(DateUtils.dateTime("yyyy-MM-dd", dto.getCreatedate()));
        this.updateById(channel);
        log.info("频道修改，id为：{}", dto.getId());

        // 保存日志，操作类型：修改【2】
        channelLogService.saveChannelLog(channel.getId(), "2");

        return channel;
    }

    @Override
    public GxhInfoChannel detailChannel(String channelId) {
        GxhInfoChannel channel = this.getById(Long.parseLong(channelId));
        return channel;
    }

    /**
     * 导出
     * @param channelVo
     * @return
     */
    @Override
    public List<GxhInfoChannel> exportList(GxhInfoChannelVo channelVo) {

        // 构造 GxhInfoChannel 搜索条件
        LambdaQueryWrapper<GxhInfoChannel> wrapper = Wrappers.lambdaQuery();
        // 名称模糊查询
        wrapper.like(StringUtils.hasText(channelVo.getName()), GxhInfoChannel::getName, channelVo.getName());
        // 分类查询
        wrapper.eq(StringUtils.hasText(channelVo.getCtype()), GxhInfoChannel::getCtype, channelVo.getCtype());

        // 日期区间查询
        if (channelVo.getQuerydate() != null && channelVo.getQuerydate().length == 2) {
            wrapper.between(GxhInfoChannel::getCreatedate, channelVo.getQuerydate()[0], channelVo.getQuerydate()[1]);
        }

        // 根据排序值倒序
        wrapper.orderByDesc(GxhInfoChannel::getOrdernum);
        List<GxhInfoChannel> channelList = this.baseMapper.selectList(wrapper);
        return channelList;
    }
}
